package com.shyroke.calculation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.shyroke.util.ConvertUtil;

import entity.ConvertExpert;
import entity.Expert;
import entity.GroupDesicionDto;
import net.bytebuddy.asm.Advice.This;

/**
 * 计算群体决策信息
 * @author shyroke
 *
 */
public class GroupDecisionInfoCal {

	/**
	 *  计算群体决策信息
	 * @param expertMap
	 * @param expertImportance
	 * @return
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 */
	public static List<GroupDesicionDto> getGroupDesion(Map<Integer, Expert> expertMap,
			Map<String, Double> expertImportance) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
		List<GroupDesicionDto> groupDecisionList = new ArrayList<>();
		GroupDesicionDto desicionDto = null;
		//循环4个属性
		for(int i=1;i<=4;i++) {
			 desicionDto = new GroupDesicionDto();
			desicionDto.setId(i);
			
			List<ConvertExpert> convertExperts = ConvertUtil.covert(expertMap);
			/**
			 * 属性1
			 */
			List<Double> x1_param1 = new ArrayList<>();  //决策方案1的1-T
			List<Double> x1_param2 = new ArrayList<>(); //决策方案1的I
			List<Double> x1_param3 = new ArrayList<>(); //决策方案1的F
			List<Double> x2_param1 = new ArrayList<>();  //决策方案2的1-T
			List<Double> x2_param2 = new ArrayList<>(); //决策方案2的I
			List<Double> x2_param3 = new ArrayList<>(); //决策方案2的F
			List<Double> x3_param1 = new ArrayList<>();  //决策方案3的1-T
			List<Double> x3_param2 = new ArrayList<>(); //决策方案3的I
			List<Double> x3_param3 = new ArrayList<>(); //决策方案3的F
			
			/**
			 * 属性2
			 * 
			 */
			List<Double> x1_param1_2 = new ArrayList<>();  //决策方案1的1-T
			List<Double> x1_param2_2 = new ArrayList<>(); //决策方案1的I
			List<Double> x1_param3_2 = new ArrayList<>(); //决策方案1的F
			List<Double> x2_param1_2 = new ArrayList<>();  //决策方案2的1-T
			List<Double> x2_param2_2 = new ArrayList<>(); //决策方案2的I
			List<Double> x2_param3_2 = new ArrayList<>(); //决策方案2的F
			List<Double> x3_param1_2 = new ArrayList<>();  //决策方案3的1-T
			List<Double> x3_param2_2 = new ArrayList<>(); //决策方案3的I
			List<Double> x3_param3_2 = new ArrayList<>(); //决策方案3的F
			
			/**
			 * 属性3
			 * 
			 */
			List<Double> x1_param1_3 = new ArrayList<>();  //决策方案1的1-T
			List<Double> x1_param2_3 = new ArrayList<>(); //决策方案1的I
			List<Double> x1_param3_3 = new ArrayList<>(); //决策方案1的F
			List<Double> x2_param1_3 = new ArrayList<>();  //决策方案2的1-T
			List<Double> x2_param2_3 = new ArrayList<>(); //决策方案2的I
			List<Double> x2_param3_3 = new ArrayList<>(); //决策方案2的F
			List<Double> x3_param1_3 = new ArrayList<>();  //决策方案3的1-T
			List<Double> x3_param2_3 = new ArrayList<>(); //决策方案3的I
			List<Double> x3_param3_3 = new ArrayList<>(); //决策方案3的F
			
			
			/**
			 * 属性4
			 * 
			 */
			List<Double> x1_param1_4 = new ArrayList<>();  //决策方案1的1-T
			List<Double> x1_param2_4 = new ArrayList<>(); //决策方案1的I
			List<Double> x1_param3_4 = new ArrayList<>(); //决策方案1的F
			List<Double> x2_param1_4 = new ArrayList<>();  //决策方案2的1-T
			List<Double> x2_param2_4 = new ArrayList<>(); //决策方案2的I
			List<Double> x2_param3_4 = new ArrayList<>(); //决策方案2的F
			List<Double> x3_param1_4 = new ArrayList<>();  //决策方案3的1-T
			List<Double> x3_param2_4 = new ArrayList<>(); //决策方案3的I
			List<Double> x3_param3_4 = new ArrayList<>(); //决策方案3的F
			
			
			//循环专家
			for(int j=1;j<=convertExperts.size();j++) {
				ConvertExpert expert = convertExperts.get(j-1);
				
				if(i==1) {//第一个属性
					//第1/2/3个方案的的中智集的方法
					Method m1 = expert.getClass().getMethod("getS11Map");
					Method m2 = expert.getClass().getMethod("getS21Map");
					Method m3 = expert.getClass().getMethod("getS31Map");
					//第1/2/3个方案的的中智集
					Map<String,List<Double>> zzj1 =(Map)m1.invoke(expert);
					Map<String,List<Double>> zzj2 =(Map)m2.invoke(expert);
					Map<String,List<Double>> zzj3 =(Map)m3.invoke(expert);
					
					//第一个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek1 = GroupDecisionInfoCal.get1Tek(zzj1.get("s11").get(0),expertImportance.get(j+""));
					double Iek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s11").get(1),expertImportance.get(j+""));
					double Fek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s11").get(2),expertImportance.get(j+""));
				
					
					//第2个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek2 = GroupDecisionInfoCal.get1Tek(zzj2.get("s21").get(0),expertImportance.get(j+""));
					double Iek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s21").get(1),expertImportance.get(j+""));
					double Fek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s21").get(2),expertImportance.get(j+""));
					
					
					//第3个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek3 = GroupDecisionInfoCal.get1Tek(zzj3.get("s31").get(0),expertImportance.get(j+""));
					double Iek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s31").get(1),expertImportance.get(j+""));
					double Fek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s31").get(2),expertImportance.get(j+""));
					
					x1_param1.add(Tek1);
					x1_param2.add(Iek1);
					x1_param3.add(Fek1);

					x2_param1.add(Tek2);
					x2_param2.add(Iek2);
					x2_param3.add(Fek2);
					
					x3_param1.add(Tek3);
					x3_param2.add(Iek3);
					x3_param3.add(Fek3);
					
				}
				
				
				
				if(i==2) {//第2个属性
					//第1/2/3个方案的的中智集的方法
					Method m1 = expert.getClass().getMethod("getS12Map");
					Method m2 = expert.getClass().getMethod("getS22Map");
					Method m3 = expert.getClass().getMethod("getS32Map");
					//第1/2/3个方案的的中智集
					Map<String,List<Double>> zzj1 =(Map)m1.invoke(expert);
					Map<String,List<Double>> zzj2 =(Map)m2.invoke(expert);
					Map<String,List<Double>> zzj3 =(Map)m3.invoke(expert);
					
					//第一个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek1 = GroupDecisionInfoCal.get1Tek(zzj1.get("s12").get(0),expertImportance.get(j+""));
					double Iek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s12").get(1),expertImportance.get(j+""));
					double Fek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s12").get(2),expertImportance.get(j+""));
				
					
					//第2个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek2 = GroupDecisionInfoCal.get1Tek(zzj2.get("s22").get(0),expertImportance.get(j+""));
					double Iek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s22").get(1),expertImportance.get(j+""));
					double Fek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s22").get(2),expertImportance.get(j+""));
					
					
					//第3个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek3 = GroupDecisionInfoCal.get1Tek(zzj3.get("s32").get(0),expertImportance.get(j+""));
					double Iek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s32").get(1),expertImportance.get(j+""));
					double Fek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s32").get(2),expertImportance.get(j+""));
					
					x1_param1_2.add(Tek1);
					x1_param2_2.add(Iek1);
					x1_param3_2.add(Fek1);

					x2_param1_2.add(Tek2);
					x2_param2_2.add(Iek2);
					x2_param3_2.add(Fek2);
					
					x3_param1_2.add(Tek3);
					x3_param2_2.add(Iek3);
					x3_param3_2.add(Fek3);
					
				}
				
				
				if(i==3) {//第3个属性
					//第1/2/3个方案的的中智集的方法
					Method m1 = expert.getClass().getMethod("getS13Map");
					Method m2 = expert.getClass().getMethod("getS23Map");
					Method m3 = expert.getClass().getMethod("getS33Map");
					//第1/2/3个方案的的中智集
					Map<String,List<Double>> zzj1 =(Map)m1.invoke(expert);
					Map<String,List<Double>> zzj2 =(Map)m2.invoke(expert);
					Map<String,List<Double>> zzj3 =(Map)m3.invoke(expert);
					
					//第一个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek1 = GroupDecisionInfoCal.get1Tek(zzj1.get("s13").get(0),expertImportance.get(j+""));
					double Iek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s13").get(1),expertImportance.get(j+""));
					double Fek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s13").get(2),expertImportance.get(j+""));
				
					
					//第2个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek2 = GroupDecisionInfoCal.get1Tek(zzj2.get("s23").get(0),expertImportance.get(j+""));
					double Iek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s23").get(1),expertImportance.get(j+""));
					double Fek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s23").get(2),expertImportance.get(j+""));
					
					
					//第3个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek3 = GroupDecisionInfoCal.get1Tek(zzj3.get("s33").get(0),expertImportance.get(j+""));
					double Iek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s33").get(1),expertImportance.get(j+""));
					double Fek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s33").get(2),expertImportance.get(j+""));
					
					x1_param1_3.add(Tek1);
					x1_param2_3.add(Iek1);
					x1_param3_3.add(Fek1);

					x2_param1_3.add(Tek2);
					x2_param2_3.add(Iek2);
					x2_param3_3.add(Fek2);
					
					x3_param1_3.add(Tek3);
					x3_param2_3.add(Iek3);
					x3_param3_3.add(Fek3);
					
				}
				
				
				
				if(i==4) {//第4个属性
					//第1/2/3个方案的的中智集的方法
					Method m1 = expert.getClass().getMethod("getS14Map");
					Method m2 = expert.getClass().getMethod("getS24Map");
					Method m3 = expert.getClass().getMethod("getS34Map");
					//第1/2/3个方案的的中智集
					Map<String,List<Double>> zzj1 =(Map)m1.invoke(expert);
					Map<String,List<Double>> zzj2 =(Map)m2.invoke(expert);
					Map<String,List<Double>> zzj3 =(Map)m3.invoke(expert);
					
					//第一个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek1 = GroupDecisionInfoCal.get1Tek(zzj1.get("s14").get(0),expertImportance.get(j+""));
					double Iek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s14").get(1),expertImportance.get(j+""));
					double Fek1 = GroupDecisionInfoCal.get1IFek(zzj1.get("s14").get(2),expertImportance.get(j+""));
				
					
					//第2个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek2 = GroupDecisionInfoCal.get1Tek(zzj2.get("s24").get(0),expertImportance.get(j+""));
					double Iek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s24").get(1),expertImportance.get(j+""));
					double Fek2 = GroupDecisionInfoCal.get1IFek(zzj2.get("s24").get(2),expertImportance.get(j+""));
					
					
					//第3个决策方案的（1-T）ek 和 Iek 和Fek
					double Tek3 = GroupDecisionInfoCal.get1Tek(zzj3.get("s34").get(0),expertImportance.get(j+""));
					double Iek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s34").get(1),expertImportance.get(j+""));
					double Fek3 = GroupDecisionInfoCal.get1IFek(zzj3.get("s34").get(2),expertImportance.get(j+""));
				
					x1_param1_4.add(Tek1);
					x1_param2_4.add(Iek1);
					x1_param3_4.add(Fek1);

					x2_param1_4.add(Tek2);
					x2_param2_4.add(Iek2);
					x2_param3_4.add(Fek2);
					
					x3_param1_4.add(Tek3);
					x3_param2_4.add(Iek3);
					x3_param3_4.add(Fek3);
					
				}
				
				
			}
			
			/**
			 * 属性1
			 */
			double x1_mult_T = GroupDecisionInfoCal.getMult_T(x1_param1);
			double x1_mult_I = GroupDecisionInfoCal.getMult_T(x1_param2);
			double x1_mult_F = GroupDecisionInfoCal.getMult_T(x1_param3);
			List<Double> x1_param_1 = GroupDecisionInfoCal.getResult(x1_mult_T, x1_mult_I, x1_mult_F);
			
			double x2_mult_T = GroupDecisionInfoCal.getMult_T(x2_param1);
			double x2_mult_I = GroupDecisionInfoCal.getMult_T(x2_param2);
			double x2_mult_F = GroupDecisionInfoCal.getMult_T(x2_param3);
			List<Double> x2_param_1 = GroupDecisionInfoCal.getResult(x2_mult_T, x2_mult_I, x2_mult_F);
			
			double x3_mult_T = GroupDecisionInfoCal.getMult_T(x3_param1);
			double x3_mult_I = GroupDecisionInfoCal.getMult_T(x3_param2);
			double x3_mult_F = GroupDecisionInfoCal.getMult_T(x3_param3);
			List<Double> x3_param_1 = GroupDecisionInfoCal.getResult(x3_mult_T, x3_mult_I, x3_mult_F);
			
			
			if(desicionDto.getId()==1) {
				desicionDto.setX1info(x1_param_1);
				desicionDto.setX2info(x2_param_1);
				desicionDto.setX3info(x3_param_1);
				groupDecisionList.add(desicionDto);
				continue;
			}
			
			
			/**
			 * 属性2
			 */
			double x1_mult_T_1 = GroupDecisionInfoCal.getMult_T(x1_param1_2);
			double x1_mult_I_1 = GroupDecisionInfoCal.getMult_T(x1_param2_2);
			double x1_mult_F_1 = GroupDecisionInfoCal.getMult_T(x1_param3_2);
			List<Double> x1_param_1_1 = GroupDecisionInfoCal.getResult(x1_mult_T_1, x1_mult_I_1, x1_mult_F_1);
			
			double x2_mult_T_1 = GroupDecisionInfoCal.getMult_T(x2_param1_2);
			double x2_mult_I_1 = GroupDecisionInfoCal.getMult_T(x2_param2_2);
			double x2_mult_F_1 = GroupDecisionInfoCal.getMult_T(x2_param3_2);
			List<Double> x2_param_1_1 = GroupDecisionInfoCal.getResult(x2_mult_T_1, x2_mult_I_1, x2_mult_F_1);
			
			double x3_mult_T_1 = GroupDecisionInfoCal.getMult_T(x3_param1_2);
			double x3_mult_I_1 = GroupDecisionInfoCal.getMult_T(x3_param2_2);
			double x3_mult_F_1 = GroupDecisionInfoCal.getMult_T(x3_param3_2);
			List<Double> x3_param_1_1 = GroupDecisionInfoCal.getResult(x3_mult_T_1, x3_mult_I_1, x3_mult_F_1);
			
			
			if(desicionDto.getId()==2) {
				desicionDto.setX1info(x1_param_1_1);
				desicionDto.setX2info(x2_param_1_1);
				desicionDto.setX3info(x3_param_1_1);
				groupDecisionList.add(desicionDto);
				continue;
			}
			
			
			/**
			 * 属性3
			 */
			double x1_mult_T_2 = GroupDecisionInfoCal.getMult_T(x1_param1_3);
			double x1_mult_I_2 = GroupDecisionInfoCal.getMult_T(x1_param2_3);
			double x1_mult_F_2 = GroupDecisionInfoCal.getMult_T(x1_param3_3);
			List<Double> x1_param_1_2 = GroupDecisionInfoCal.getResult(x1_mult_T_2, x1_mult_I_2, x1_mult_F_2);
			
			double x2_mult_T_2 = GroupDecisionInfoCal.getMult_T(x2_param1_3);
			double x2_mult_I_2 = GroupDecisionInfoCal.getMult_T(x2_param2_3);
			double x2_mult_F_2 = GroupDecisionInfoCal.getMult_T(x2_param3_3);
			List<Double> x2_param_1_2 = GroupDecisionInfoCal.getResult(x2_mult_T_2, x2_mult_I_2, x2_mult_F_2);
			
			double x3_mult_T_2 = GroupDecisionInfoCal.getMult_T(x3_param1_3);
			double x3_mult_I_2 = GroupDecisionInfoCal.getMult_T(x3_param2_3);
			double x3_mult_F_2 = GroupDecisionInfoCal.getMult_T(x3_param3_3);
			List<Double> x3_param_1_2 = GroupDecisionInfoCal.getResult(x3_mult_T_2, x3_mult_I_2, x3_mult_F_2);
			
			
			if(desicionDto.getId()==3) {
				desicionDto.setX1info(x1_param_1_2);
				desicionDto.setX2info(x2_param_1_2);
				desicionDto.setX3info(x3_param_1_2);
				groupDecisionList.add(desicionDto);
				continue;
			}
			
			
			/**
			 * 属性4
			 */
			double x1_mult_T_3 = GroupDecisionInfoCal.getMult_T(x1_param1_4);
			double x1_mult_I_3 = GroupDecisionInfoCal.getMult_T(x1_param2_4);
			double x1_mult_F_3 = GroupDecisionInfoCal.getMult_T(x1_param3_4);
			List<Double> x1_param_1_3 = GroupDecisionInfoCal.getResult(x1_mult_T_3, x1_mult_I_3, x1_mult_F_3);
			
			double x2_mult_T_3 = GroupDecisionInfoCal.getMult_T(x2_param1_4);
			double x2_mult_I_3 = GroupDecisionInfoCal.getMult_T(x2_param2_4);
			double x2_mult_F_3 = GroupDecisionInfoCal.getMult_T(x2_param3_4);
			List<Double> x2_param_1_3 = GroupDecisionInfoCal.getResult(x2_mult_T_3, x2_mult_I_3, x2_mult_F_3);
			
			double x3_mult_T_3 = GroupDecisionInfoCal.getMult_T(x3_param1_4);
			double x3_mult_I_3 = GroupDecisionInfoCal.getMult_T(x3_param2_4);
			double x3_mult_F_3 = GroupDecisionInfoCal.getMult_T(x3_param3_4);
			List<Double> x3_param_1_3 = GroupDecisionInfoCal.getResult(x3_mult_T_3, x3_mult_I_3, x3_mult_F_3);
			
			
			if(desicionDto.getId()==4) {
				desicionDto.setX1info(x1_param_1_3);
				desicionDto.setX2info(x2_param_1_3);
				desicionDto.setX3info(x3_param_1_3);
				groupDecisionList.add(desicionDto);
				continue;
			}
			
		}
		
		return groupDecisionList;
	}

	
	
	/**
	 * @param T 中智集
	 * @param expertImportance 专家的重要性
	 * 计算（1-T）^ek 
	 * @return
	 */
	public static double get1Tek(Double T,Double expertImportance) {
		double param = 1-T;
		
		return  Math.pow(param, expertImportance);
	}
	
	/**
	 * @param IF 中智集
	 * @param expertImportance 专家的重要性
	 * 计算 I^ek 或者 F^ek
	 * @return
	 */
	public static double get1IFek(double IF,double expertImportance) {
		
		return  Math.pow(IF, expertImportance);
	}
	
	
	/**
	 * 计算T/I/F乘积
	 * @return
	 */
	public static double getMult_T(List<Double> param) {
		double result=1;
		
		for(double arg:param) {
			result = result*arg;
		}
		
		return result;
	}
	
	/**
	 * 
	 * @param mult_T T乘积
	 * @param mult_I I乘积
	 * @param mult_F F乘积
	 * @return
	 */
	public static List<Double> getResult(double mult_T,double mult_I,double mult_F){
		List<Double> result = new ArrayList<>();
		result.add(Double.valueOf(new DecimalFormat("#.000").format(1-mult_T)));
		result.add(Double.valueOf(new DecimalFormat("#.000").format(mult_I)));
		result.add(Double.valueOf(new DecimalFormat("#.000").format(mult_F)));
		return result;
	}
	
}
